package com.xyzwps.paimon.furina.modules.post.entity

import com.xyzwps.paimon.furina.common.DateTimeUtil
import com.xyzwps.paimon.furina.common.DeleteOption
import com.xyzwps.paimon.furina.common.DeleteOption.*
import org.jetbrains.exposed.sql.*
import org.springframework.stereotype.Repository

@Repository
class PostCollectionRepository {

    private val t = PostCollection.Companion.TABLE

    fun findByUserId(userId: Long, option: DeleteOption = UNDELETED_ONLY): List<PostCollection> {
        val condition = when (option) {
            UNDELETED_ONLY -> Op.build { t.userId eq userId and t.deleteTime.isNull() }
            DELETED_ONLY -> Op.build { t.userId eq userId and t.deleteTime.isNotNull() }
            ALL -> Op.build { t.userId eq userId }
        }
        return t.select(condition).map { PostCollection(it) }
    }

    fun findById(id: Long, option: DeleteOption = UNDELETED_ONLY): PostCollection? {
        val condition = when (option) {
            UNDELETED_ONLY -> Op.build { (t.id eq id) and t.deleteTime.isNull() }
            DELETED_ONLY -> Op.build { (t.id eq id) and t.deleteTime.isNotNull() }
            ALL -> Op.build { t.id eq id }
        }
        return t.select(condition).map { PostCollection(it) }.firstOrNull()
    }

    fun findByIds(ids: Collection<Long>, option: DeleteOption = UNDELETED_ONLY): List<PostCollection> {
        if (ids.isEmpty()) return emptyList()

        val condition = when (option) {
            UNDELETED_ONLY -> Op.build { (t.id inList ids) and t.deleteTime.isNull() }
            DELETED_ONLY -> Op.build { (t.id inList ids) and t.deleteTime.isNotNull() }
            ALL -> Op.build { t.id inList ids }
        }
        return t.select(condition).map { PostCollection(it) }
    }

    fun update(collection: PostCollection) {
        t.update({ t.id eq collection.id }) {
            it[t.title] = collection.title
            it[t.deleteTime] = collection.deleteTime
            it[t.updateTime] = collection.updateTime
        }
    }

    fun create(userId: Long, title: String): PostCollection {
        val id = t.insertAndGetId {
            it[t.userId] = userId
            it[t.title] = title
            it[t.createTime] = DateTimeUtil.currentLocalDateTime()
            it[t.deleteTime] = null
            it[t.updateTime] = DateTimeUtil.currentLocalDateTime()
        }
        return findById(id.value)!!
    }
}